#include "PipeServer.h"

//-----------------------------------------------------------------------------
DWORD WINAPI InstanceThread(LPVOID InParam)
{
    unsigned char Buff[BUFSIZE];    
    DWORD cbBytesRead;    
    PipeClientThread *ThreadData = (PipeClientThread*)InParam;
    PipeServer *Server = (PipeServer*)ThreadData->Server;
    BOOL fSuccess = FALSE;
    while(1 == 1)
    {
        fSuccess = ReadFile( 
         ThreadData->hPipe,        // handle to pipe 
         Buff,    // buffer to receive data 
         BUFSIZE, // size of buffer 
         &cbBytesRead, // number of bytes read 
         NULL);       
         if(!fSuccess || cbBytesRead == 0)
         {
             cbBytesRead = GetLastError();
             if(cbBytesRead == ERROR_BROKEN_PIPE)
             {
                Server->WxDebug("Client chiuso");      
               DisconnectNamedPipe(ThreadData->hPipe); 
               CloseHandle(ThreadData->hPipe);                              
               return 0;
             }   
         } 
         else
         {
             Server->WxDebug("Ricezione dati da client: bytes %d",cbBytesRead);
             Sleep(10); //...
              fSuccess = WriteFile( 
             ThreadData->hPipe,        // handle to pipe 
             Buff,     // buffer to write from 
             cbBytesRead, // number of bytes to write 
             &cbBytesRead,   // number of bytes written 
             NULL);       
             Server->WxDebug("Invio dati al client: bytes %d",cbBytesRead);          
             Sleep(1);
        }
    }
   FlushFileBuffers(ThreadData->hPipe); 
   DisconnectNamedPipe(ThreadData->hPipe); 
   CloseHandle(ThreadData->hPipe);     
}
//-----------------------------------------------------------------------------
DWORD WINAPI MainServerThread(LPVOID InParam)
{
    HANDLE hPipe;
    PipeClientThread *ClientThread;
    PipeServerThread *ThreadData = (PipeServerThread*)InParam;
    PipeServer *Server = (PipeServer*)ThreadData->Server;
    DWORD Read;
    BOOL   fConnected = FALSE; 
	char *tmp = (char*)malloc(strlen(ThreadData->PipeName)+0x20);
	memset(tmp,0,strlen(ThreadData->PipeName)+0x20);
	sprintf(tmp,"\\\\.\\pipe\\%s",ThreadData->PipeName);    
    while(1==1)
    {
        ClientThread = (PipeClientThread*)malloc(sizeof(PipeClientThread));
        ClientThread->hPipe = CreateNamedPipe( 
          tmp,             // pipe name 
          PIPE_ACCESS_DUPLEX,       // read/write access 
          PIPE_TYPE_MESSAGE |       // message type pipe 
          PIPE_READMODE_MESSAGE |   // message-read mode 
          PIPE_WAIT,                // blocking mode 
          PIPE_UNLIMITED_INSTANCES, // max. instances  
          BUFSIZE,                  // output buffer size 
          BUFSIZE,                  // input buffer size 
          0,                        // client time-out 
          NULL);  
          if (ClientThread->hPipe == INVALID_HANDLE_VALUE)
          {
            Read = GetLastError(); 
            Server->WxDebug("Errore nell'esecuzione CreateNamedPipe: errore %d",Read);
          }      
          else
          {
            fConnected = ConnectNamedPipe(ClientThread->hPipe, NULL) ? 
             TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);      
            if(fConnected)
            {
                ClientThread->Server = Server;
                ClientThread->Thread = CreateThread(NULL,BUFSIZE * 3,InstanceThread,ClientThread,0, NULL);
                if(ClientThread->Thread == NULL)
                {
                    Read = GetLastError();   
                    Server->WxDebug("Errore nella creazione InstanceThread: errore %d",Read);             
                }
            }
            else
            {
                Read = GetLastError();
                Server->WxDebug("Errore nell'esecuzione ConnectNamedPipe: errore %d",Read);
                CloseHandle(ClientThread->hPipe);            
            }
          }
    }        
}
//-----------------------------------------------------------------------------
PipeServer::PipeServer(void)
{
    FPipeName = NULL;
    LogFile = NULL;
}
//-----------------------------------------------------------------------------
DWORD PipeServer::Connect(char *Name)
{
    if(Name != NULL)
    {
        int Len = strlen(Name);
        FPipeName = (char*)malloc(Len+1);
        memset(FPipeName,0,Len+1);
        memcpy(FPipeName,Name,Len);
        ThreadInfo.PipeName = FPipeName;
        ThreadInfo.Server = this;
        MainThread = CreateThread(NULL,BUFSIZE * 3,MainServerThread,&ThreadInfo,0, NULL);
        if(MainThread == NULL)
        {
            DWORD Err = GetLastError();
            WxDebug("Creazione server con errore %d",Err);
            return PIPE_BAD_CONNECTION;
        }   
        else
        {
            WxDebug("Server creato per il pipe %s",FPipeName);
            return PIPE_CORRECT_OPERATION;        
        }
    }
    return PIPE_NO_OPERATION;
}
//-----------------------------------------------------------------------------
void PipeServer::WxDebug(char *Format,...)
{
	SYSTEMTIME Now;
	GetLocalTime(&Now);
    
    char Msg[0x400];
	memset(Msg,0,0x400);
	sprintf(Msg,"[%02d/%02d/%2d-%02d:%02d:%02d.%03d]",Now.wDay,Now.wMonth,
				Now.wYear%100,Now.wHour,Now.wMinute,Now.wSecond,Now.wMilliseconds);
	
    va_list args;
    va_start (args, Format);
    vsprintf (Msg+strlen(Msg),Format, args);
    va_end (args);    
	if(LogFile != NULL)
	{
//		if(Level<=Utility->DebugLevel)
//			Utility->FormatLogToFile(LogFile,Msg);
	FILE  *out;
	out = fopen(LogFile,"a");
	int MsgLen=strlen(Msg);
	char *Temp = (char*)malloc(MsgLen+2);
	memcpy(Temp,Msg,MsgLen);
	if(Temp[MsgLen-1]!='\n')
	{
		if(Temp[MsgLen-2]!='\r')
		{
			Temp[MsgLen]='\r';
			Temp[MsgLen+1]='\n';
			MsgLen+=2;
		}
		else
		{
            Temp[MsgLen-1]='\n';
        }
    }
	else
	{
		if(Temp[MsgLen-1]=='\r')
		{
			Temp[MsgLen]='\n';
			MsgLen++;
		}
		else
		{
			memcpy(Temp+MsgLen,"\r\n",2);
			MsgLen+=2;
		}
	}
//	WriteFile(File,Temp,MsgLen,&Len,NULL);
//	CloseHandle(File);
	fwrite(Temp,MsgLen,1,out);
	fclose(out);
//	return 0;
	}    
}
//-----------------------------------------------------------------------------
